/**
 * 
 */
package com.speljohan.rsbot.script.wrappers;

import java.awt.Point;
import java.awt.Rectangle;

import com.speljohan.rsbot.accessors.Interface;

/**
 * This class handles an Interface Child The class RSInterface references to
 * this one a lot
 * 
 * @author Qauters
 */
public class RSInterfaceChild {
	/**
	 * The index of this interface in the parent.
	 * */
	private final int index;
	/**
	 * The parent interface containing this child.
	 * */
	private final RSInterface parInterface;

	/**
	 * Initializes the child.
	 */
	RSInterfaceChild(final RSInterface parent, final int index) {
		parInterface = parent;
		this.index = index;
	}

	/**
	 * Checks the actions of the child for a given text phrase
	 * 
	 * @param phrase
	 *            The phrase to check for
	 * @return true if found
	 */
	public boolean containsAction(final String phrase) {
		for (final String action : getActions()) {
			if (action.toLowerCase().contains(phrase.toLowerCase())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Checks the text of the child for a given text phrase
	 * 
	 * @param phrase
	 *            The phrase to check for
	 * @return Whether the text contained the phrase or niot
	 */
	public boolean containsText(final String phrase) {
		return getText().contains(phrase);
	}

	@Override
	public boolean equals(final Object obj) {
		if (obj == this) {
			return true;
		}
		if (obj instanceof RSInterfaceChild) {
			final RSInterfaceChild child = (RSInterfaceChild) obj;
			if (index != child.index) {
				return false;
			}
			return child.parInterface.equals(parInterface);
		}
		return false;
	}

	/**
	 * Get's the absolute x position of the child, calculated from the beginning
	 * of the rs screen
	 * 
	 * @return the absolute x or -1 if null
	 */
	public int getAbsoluteX() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getMasterX() + inter.getX();
		}
		return -1;
	}

	/**
	 * Get's the absolute y position of the child, calculated from the beginning
	 * of the rs screen
	 * 
	 * @return the absolute y position or -1 if null
	 */
	public int getAbsoluteY() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			return childInterface.getMasterY() + childInterface.getY();
		}
		return -1;
	}

	/**
	 * Get's the actions of the child. The elements will never be null.
	 * 
	 * @return the actions or an empty array if null
	 */
	public String[] getActions() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getActions();
		}
		return new String[0];
	}

	/**
	 * Get's the action type of the child
	 * 
	 * @return the action type or -1 if null
	 */
	public int getActionType() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getActionType();
		}
		return -1;
	}

	/**
	 * Get's the Area of the child, calculated from it's absolute position
	 * 
	 * @return the area or new Rectangle(-1, -1, -1, -1) if null
	 */
	public Rectangle getArea() {
		return new Rectangle(getAbsoluteX(), getAbsoluteY(), getWidth(),
				getHeight());
	}

	/**
	 * Get's the background color of the child
	 * 
	 * @return the background color or -1 if null
	 */
	public int getBackgroundColor() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getBackgroundColor();
		}
		return -1;
	}

	public int getBorderThickness() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getTextColour();
		}
		return -1;
	}

	/**
	 * return component ID of child Used for "Unsolvable" randoms.
	 * 
	 * @return Component ID
	 * @author PwnZ
	 */

	public int getComponentID() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getComponentID();
		}
		return -1;
	}

	/**
	 * The components (bank items etc) of this interface.
	 * 
	 * @return The components or RSInterfaceComponent[0] if this child is
	 *         invalid.
	 */
	public RSInterfaceComponent[] getComponents() {
		final Interface inter = getInterfaceInternal();
		if (inter != null && inter.getCache() != null) {
			final RSInterfaceComponent[] components = new RSInterfaceComponent[inter
			                                                                   .getCache().length];
			for (int i = 0; i < inter.getCache().length; i++) {
				components[i] = new RSInterfaceComponent(parInterface, index, i);
			}
			return components;
		}
		return new RSInterfaceComponent[0];
	}

	/**
	 * Get's the height of the child
	 * 
	 * @return the height of the child or -1 if null
	 */
	public int getHeight() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			return childInterface.getHeight() - 4;
		}
		return -1;
	}

	public int getHorizontalScrollBarSize() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getHorizontalScrollBarSize();
		}
		return -1;

	}

	public int getHorizontalScrollBarThumbPosition() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getHorizontalScrollBarThumbPosition();
		}
		return -1;

	}

	public int getHorizontalScrollBarThumbSize() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getHorizontalScrollBarThumbSize();
		}
		return -1;

	}

	public int getID() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getID();
		}
		return -1;

	}

	/**
	 * Gets the index of this interface.
	 * */
	public int getIndex() {
		return index;
	}

	/**
	 * Gets the interface represented by this object.
	 * */
	Interface getInterfaceInternal() {
		final Interface[] children = parInterface.getChildrenInternal();
		if (children != null && index < children.length) {
			return children[index];
		}
		return null;
	}

	/**
	 * Get's the inventory of the child, automatically corrects item ids.
	 * 
	 * @return the inventory of the child or new int[0] if null
	 */
	public int[] getInventory() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			final int[] inv = childInterface.getInventory();
			if (inv != null) {
				final int[] out = new int[inv.length];
				for (int i = 0; i < inv.length; i++) {
					out[i] = inv[i] - 1;
				}
				return out;
			}
		}
		return new int[0];
	}

	/**
	 * returns the amount of specified items, you have in your inventory
	 * 
	 * @param itemIDs
	 *            the item Ids to search for
	 * @return the amount of items you have, it checks it stack size aswell
	 */
	public int getInventoryItemCount(final int... itemIDs) {
		int count = 0;
		final int[] inventory = getInventory();
		for (int off = 0; off < inventory.length; off++) {
			final int inv = inventory[off];
			for (final int element : itemIDs) {
				if (inv == element) {
					count += getInventoryStackSizes()[off];
				}
			}
		}
		return count;
	}

	/**
	 * Get's the inventory stack sizes of the child
	 * 
	 * @return the inventory stack sizes or new int[0] if null
	 */
	public int[] getInventoryStackSizes() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			final int[] inv = childInterface.getInventoryStackSizes();
			if (inv != null) {
				return inv.clone();
			}
		}
		// clone, otherwise you have a pointer
		return new int[0];
	}

	/**
	 * Get's the inventory sprite pad of the child God know's what it get, I'll
	 * check it out later
	 * 
	 * @return the inventory sprite pad or new Point(-1, -1) if null
	 */
	public Point getInvSpritePad() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return new Point(inter.getInvSpritePadX(), inter.getInvSpritePadY());
		}
		return new Point(-1, -1);
	}

	/**
	 * Get's the model ID of the child
	 * 
	 * @return the model ID or -1 if null
	 */
	public int getModelID() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			int id = inter.getInterfaceSelectedModelID();
			if (id == -1) {
				id = inter.getNotInterfaceSelectedModelID();
			}
			return id;
		}
		return -1;
	}

	/**
	 * Get's the model type of the child
	 * 
	 * @return the model type or -1 if null
	 */
	public int getModelType() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			int type = inter.getInterfaceSelectedModelType();
			if (type == -1) {
				type = inter.getNotInterfaceSelectedModelType();
			}
			return type;
		}
		return -1;
	}

	public int getModelZoom() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getModelZoom();
		}
		return -1;

	}

	public int getParentID() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getParentID();
		}
		return -1;

	}

	/**
	 * Gets the parent interface.
	 * */
	public RSInterface getParInterface() {
		return parInterface;
	}

	/**
	 * Get's the absolute position of the child
	 * 
	 * @return the absolute position or new Point(-1, -1) if null
	 */
	public Point getPosition() {
		return new Point(getAbsoluteX(), getAbsoluteY());
	}

	/**
	 * Get's the relative x position of the child, calculated from the beginning
	 * of the interface
	 * 
	 * @return the relative x position or -1 if null
	 */
	public int getRelativeX() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			return childInterface.getX();
		}
		return -1;
	}

	/**
	 * Get's the relative y position of the child, calculated from the beginning
	 * of the interface
	 * 
	 * @return the relative y position -1 if null
	 */
	public int getRelativeY() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			return childInterface.getY();
		}
		return -1;
	}

	/**
	 * Get's the selected action name of the child
	 * 
	 * @return the selected action name or "" if null
	 */
	public String getSelectedActionName() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getSelectedActionName();
		}
		return "";
	}

	public int getShadowColor() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getShadowColor();
		}
		return -1;

	}

	/**
	 * Get's the spell name of the child
	 * 
	 * @return the spell name or "" if null
	 */
	public String getSpellName() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getSpellName();
		}
		return "";
	}

	/**
	 * Get's the text of the child
	 * 
	 * @return the txt or "" if null
	 */
	public String getText() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getText();
		}
		return "";
	}

	/**
	 * Get's the text colour of the child
	 * 
	 * @return the text colour or -1 if null
	 */
	public int getTextColour() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getTextColour();
		}
		return -1;
	}

	/**
	 * Get's the tooltip of the child
	 * 
	 * @return the tooltip or "" if null
	 */
	public String getTooltip() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getToolTip();
		}
		return "";
	}

	/**
	 * Get's the type of the child
	 * 
	 * @return the type or -1 if null
	 */
	public int getType() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getType();
		}
		return -1;
	}

	/**
	 * Get's the value index array of the child Haven't checked what it does yet
	 * 
	 * @return the value index array or new int[0][0] if null
	 */
	public int[][] getValueIndexArray() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			final int[][] vindex = childInterface.getValueIndexArray();
			if (vindex != null) { // clone does NOT deep copy
				final int[][] out = new int[vindex.length][0];
				for (int i = 0; i < vindex.length; i++) {
					final int[] cur = vindex[i];
					if (cur != null) {
						out[i] = cur.clone();
					}
				}
				return out;
			}
		}
		// clone, otherwise you have a pointer
		return new int[0][0];
	}

	public int getVerticalScrollBarPosition() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getVerticalScrollBarPosition();
		}
		return -1;

	}

	public int getVerticalScrollBarSize() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getVerticalScrollBarSize();
		}
		return -1;

	}

	public int getVerticalScrollBarThumbSize() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getVerticalScrollBarThumbSize();
		}
		return -1;

	}

	/**
	 * Get's the width of the child
	 * 
	 * @return the width of the child or -1 if null
	 */
	public int getWidth() {
		final Interface childInterface = getInterfaceInternal();
		if (childInterface != null) {
			return childInterface.getWidth() - 4;
		}
		return -1;
	}

	/**
	 * Get the xRotation of the interface.
	 * 
	 * @return xRotation of the interface
	 */
	public int getXRotation() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getXRotation();
		}
		return -1;

	}

	public int getYRotation() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getYRotation();
		}
		return -1;

	}

	public int getZRotation() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.getZRotation();
		}
		return -1;
	}

	@Override
	public int hashCode() {
		return parInterface.getIndex() * 31 + index;
	}

	public boolean isHorizontallyFlipped() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.isHorizontallyFlipped();
		}
		return false;

	}

	/**
	 * Whether the child is an inventory interface or not
	 * 
	 * @return True if it's an inventory interface, else false
	 */
	public boolean isInventoryInterface() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.isInventoryInterface();
		}
		return false;
	}

	/**
	 * Check's whether or not the child is valid
	 * 
	 * @return true if not valid
	 */
	@Deprecated
	public boolean isNull() {
		return !isValid();
	}

	/**
	 * Check's whether or not the child is valid.
	 */
	public boolean isValid() {
		if (!parInterface.isValid()) {
			return false;
		}
		return parInterface.getChildrenInternal() != null;
	}

	public boolean isVerticallyFlipped() {
		final Interface inter = getInterfaceInternal();
		if (inter != null) {
			return inter.isVerticallyFlipped();
		}
		return false;

	}
}
